package cn.zn.framework.common.exception;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.zn.framework.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 异常处理器
 */
@RestControllerAdvice//(annotations = RestController.class)
@Slf4j
public class RRExceptionHandler {

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(RRException.class)
    public R handleRRException(RRException e) {
        log.error(e.getMessage(), e);
        R r = new R();
        r.put("code", e.getCode());
        r.put("msg", e.getMessage());
        return r;
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public R handlerNoFoundException(Exception e) {
        log.error(e.getMessage(), e);
        return R.error(HttpStatus.HTTP_NOT_FOUND, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public R handleDuplicateKeyException(DuplicateKeyException e) {
        log.error(e.getMessage(), e);
        return R.error("已存在相同的记录");
    }

    @ExceptionHandler(AuthorizationException.class)
    public R handleAuthorizationException(AuthorizationException e) {
        log.error(e.getMessage(), e);
        return R.error(HttpStatus.HTTP_UNAUTHORIZED, "没有权限，请联系管理员授权");
    }

    @ExceptionHandler(MultipartException.class)
    public R handleFileSizeLimitExceededException(MultipartException e) {
        log.error(e.getMessage(), e);
        return R.error(HttpStatus.HTTP_BAD_REQUEST, "上传文件超出限制大小,单个文件不要超过200K，多个文件总大小不要超过10M");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R handleArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        BindingResult bindingResult = e.getBindingResult();
        List<String> errors = bindingResult.getFieldErrors().stream().map(o -> o.getField().concat(o.getDefaultMessage())).collect(Collectors.toList());
        return R.error(HttpStatus.HTTP_BAD_REQUEST, StrUtil.join(";", errors));
    }

    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        log.error(e.getMessage(), e);
        return R.error();
    }
}
